home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / HTMLParser.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2005-10-18  |  11KB  |  326 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.4)
  3.  
  4. '''A parser for HTML and XHTML.'''
  5. import markupbase
  6. import re
  7. interesting_normal = re.compile('[&<]')
  8. interesting_cdata = re.compile('<(/|\\Z)')
  9. incomplete = re.compile('&[a-zA-Z#]')
  10. entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
  11. charref = re.compile('&#(?:[0-9]+|[xX][0-9a-fA-F]+)[^0-9a-fA-F]')
  12. starttagopen = re.compile('<[a-zA-Z]')
  13. piclose = re.compile('>')
  14. commentclose = re.compile('--\\s*>')
  15. tagfind = re.compile('[a-zA-Z][-.a-zA-Z0-9:_]*')
  16. attrfind = re.compile('\\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\\s*=\\s*(\\\'[^\\\']*\\\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\\(\\)_#=~@]*))?')
  17. locatestarttagend = re.compile('\n  <[a-zA-Z][-.a-zA-Z0-9:_]*          # tag name\n  (?:\\s+                             # whitespace before attribute name\n    (?:[a-zA-Z_][-.:a-zA-Z0-9_]*     # attribute name\n      (?:\\s*=\\s*                     # value indicator\n        (?:\'[^\']*\'                   # LITA-enclosed value\n          |\\"[^\\"]*\\"                # LIT-enclosed value\n          |[^\'\\">\\s]+                # bare value\n         )\n       )?\n     )\n   )*\n  \\s*                                # trailing whitespace\n', re.VERBOSE)
  18. endendtag = re.compile('>')
  19. endtagfind = re.compile('</\\s*([a-zA-Z][-.a-zA-Z0-9:_]*)\\s*>')
  20.  
  21. class HTMLParseError(Exception):
  22.     '''Exception raised for all parse errors.'''
  23.     
  24.     def __init__(self, msg, position = (None, None)):
  25.         self.msg = msg
  26.         self.lineno = position[0]
  27.         self.offset = position[1]
  28.  
  29.     
  30.     def __str__(self):
  31.         result = self.msg
  32.         if self.lineno is not None:
  33.             result = result + ', at line %d' % self.lineno
  34.         
  35.         if self.offset is not None:
  36.             result = result + ', column %d' % (self.offset + 1)
  37.         
  38.         return result
  39.  
  40.  
  41.  
  42. class HTMLParser(markupbase.ParserBase):
  43.     '''Find tags and other markup and call handler functions.
  44.  
  45.     Usage:
  46.         p = HTMLParser()
  47.         p.feed(data)
  48.         ...
  49.         p.close()
  50.  
  51.     Start tags are handled by calling self.handle_starttag() or
  52.     self.handle_startendtag(); end tags by self.handle_endtag().  The
  53.     data between tags is passed from the parser to the derived class
  54.     by calling self.handle_data() with the data as argument (the data
  55.     may be split up in arbitrary chunks).  Entity references are
  56.     passed by calling self.handle_entityref() with the entity
  57.     reference as the argument.  Numeric character references are
  58.     passed to self.handle_charref() with the string containing the
  59.     reference as the argument.
  60.     '''
  61.     CDATA_CONTENT_ELEMENTS = ('script', 'style')
  62.     
  63.     def __init__(self):
  64.         '''Initialize and reset this instance.'''
  65.         self.reset()
  66.  
  67.     
  68.     def reset(self):
  69.         '''Reset this instance.  Loses all unprocessed data.'''
  70.         self.rawdata = ''
  71.         self.lasttag = '???'
  72.         self.interesting = interesting_normal
  73.         markupbase.ParserBase.reset(self)
  74.  
  75.     
  76.     def feed(self, data):
  77.         """Feed data to the parser.
  78.  
  79.         Call this as often as you want, with as little or as much text
  80.         as you want (may include '
  81. ').
  82.         """
  83.         self.rawdata = self.rawdata + data
  84.         self.goahead(0)
  85.  
  86.     
  87.     def close(self):
  88.         '''Handle any buffered data.'''
  89.         self.goahead(1)
  90.  
  91.     
  92.     def error(self, message):
  93.         raise HTMLParseError(message, self.getpos())
  94.  
  95.     __starttag_text = None
  96.     
  97.     def get_starttag_text(self):
  98.         """Return full source of start tag: '<...>'."""
  99.         return self._HTMLParser__starttag_text
  100.  
  101.     
  102.     def set_cdata_mode(self):
  103.         self.interesting = interesting_cdata
  104.  
  105.     
  106.     def clear_cdata_mode(self):
  107.         self.interesting = interesting_normal
  108.  
  109.     
  110.     def goahead(self, end):
  111.         rawdata = self.rawdata
  112.         i = 0
  113.         n = len(rawdata)
  114.         while i < n:
  115.             match = self.interesting.search(rawdata, i)
  116.             if match:
  117.                 j = match.start()
  118.             else:
  119.                 j = n
  120.             if i < j:
  121.                 self.handle_data(rawdata[i:j])
  122.             
  123.             i = self.updatepos(i, j)
  124.             if i == n:
  125.                 break
  126.             
  127.             startswith = rawdata.startswith
  128.             None if startswith('<', i) else match
  129.             if startswith('&', i):
  130.                 match = entityref.match(rawdata, i)
  131.                 if match:
  132.                     name = match.group(1)
  133.                     self.handle_entityref(name)
  134.                     k = match.end()
  135.                     if not startswith(';', k - 1):
  136.                         k = k - 1
  137.                     
  138.                     i = self.updatepos(i, k)
  139.                     continue
  140.                 
  141.                 match = incomplete.match(rawdata, i)
  142.                 if match:
  143.                     if end and match.group() == rawdata[i:]:
  144.                         self.error('EOF in middle of entity or char ref')
  145.                     
  146.                     break
  147.                 elif i + 1 < n:
  148.                     self.handle_data('&')
  149.                     i = self.updatepos(i, i + 1)
  150.                 else:
  151.                     break
  152.             match
  153.         if end and i < n:
  154.             self.handle_data(rawdata[i:n])
  155.             i = self.updatepos(i, n)
  156.         
  157.         self.rawdata = rawdata[i:]
  158.  
  159.     
  160.     def parse_pi(self, i):
  161.         rawdata = self.rawdata
  162.         match = piclose.search(rawdata, i + 2)
  163.         if not match:
  164.             return -1
  165.         
  166.         j = match.start()
  167.         self.handle_pi(rawdata[i + 2:j])
  168.         j = match.end()
  169.         return j
  170.  
  171.     
  172.     def parse_starttag(self, i):
  173.         self._HTMLParser__starttag_text = None
  174.         endpos = self.check_for_whole_start_tag(i)
  175.         if endpos < 0:
  176.             return endpos
  177.         
  178.         rawdata = self.rawdata
  179.         self._HTMLParser__starttag_text = rawdata[i:endpos]
  180.         attrs = []
  181.         match = tagfind.match(rawdata, i + 1)
  182.         k = match.end()
  183.         self.lasttag = tag = rawdata[i + 1:k].lower()
  184.         while k < endpos:
  185.             m = attrfind.match(rawdata, k)
  186.             if not m:
  187.                 break
  188.             
  189.             (attrname, rest, attrvalue) = m.group(1, 2, 3)
  190.             if not rest:
  191.                 attrvalue = None
  192.             elif "'" == "'":
  193.                 pass
  194.             elif not "'" == attrvalue[-1:]:
  195.                 if '"' == '"':
  196.                     pass
  197.                 elif '"' == attrvalue[-1:]:
  198.                     attrvalue = attrvalue[1:-1]
  199.                     attrvalue = self.unescape(attrvalue)
  200.                 
  201.             attrs.append((attrname.lower(), attrvalue))
  202.             k = m.end()
  203.             continue
  204.             attrvalue[:1]
  205.         end = rawdata[k:endpos].strip()
  206.         if end not in ('>', '/>'):
  207.             (lineno, offset) = self.getpos()
  208.             if '\n' in self._HTMLParser__starttag_text:
  209.                 lineno = lineno + self._HTMLParser__starttag_text.count('\n')
  210.                 offset = len(self._HTMLParser__starttag_text) - self._HTMLParser__starttag_text.rfind('\n')
  211.             else:
  212.                 offset = offset + len(self._HTMLParser__starttag_text)
  213.             self.error('junk characters in start tag: %r' % (rawdata[k:endpos][:20],))
  214.         
  215.         if end.endswith('/>'):
  216.             self.handle_startendtag(tag, attrs)
  217.         else:
  218.             self.handle_starttag(tag, attrs)
  219.             if tag in self.CDATA_CONTENT_ELEMENTS:
  220.                 self.set_cdata_mode()
  221.             
  222.         return endpos
  223.  
  224.     
  225.     def check_for_whole_start_tag(self, i):
  226.         rawdata = self.rawdata
  227.         m = locatestarttagend.match(rawdata, i)
  228.         if m:
  229.             j = m.end()
  230.             next = rawdata[j:j + 1]
  231.             if next == '>':
  232.                 return j + 1
  233.             
  234.             if next == '/':
  235.                 if rawdata.startswith('/>', j):
  236.                     return j + 2
  237.                 
  238.                 if rawdata.startswith('/', j):
  239.                     return -1
  240.                 
  241.                 self.updatepos(i, j + 1)
  242.                 self.error('malformed empty start tag')
  243.             
  244.             if next == '':
  245.                 return -1
  246.             
  247.             if next in 'abcdefghijklmnopqrstuvwxyz=/ABCDEFGHIJKLMNOPQRSTUVWXYZ':
  248.                 return -1
  249.             
  250.             self.updatepos(i, j)
  251.             self.error('malformed start tag')
  252.         
  253.         raise AssertionError('we should not get here!')
  254.  
  255.     
  256.     def parse_endtag(self, i):
  257.         rawdata = self.rawdata
  258.         match = endendtag.search(rawdata, i + 1)
  259.         if not match:
  260.             return -1
  261.         
  262.         j = match.end()
  263.         match = endtagfind.match(rawdata, i)
  264.         if not match:
  265.             self.error('bad end tag: %r' % (rawdata[i:j],))
  266.         
  267.         tag = match.group(1)
  268.         self.handle_endtag(tag.lower())
  269.         self.clear_cdata_mode()
  270.         return j
  271.  
  272.     
  273.     def handle_startendtag(self, tag, attrs):
  274.         self.handle_starttag(tag, attrs)
  275.         self.handle_endtag(tag)
  276.  
  277.     
  278.     def handle_starttag(self, tag, attrs):
  279.         pass
  280.  
  281.     
  282.     def handle_endtag(self, tag):
  283.         pass
  284.  
  285.     
  286.     def handle_charref(self, name):
  287.         pass
  288.  
  289.     
  290.     def handle_entityref(self, name):
  291.         pass
  292.  
  293.     
  294.     def handle_data(self, data):
  295.         pass
  296.  
  297.     
  298.     def handle_comment(self, data):
  299.         pass
  300.  
  301.     
  302.     def handle_decl(self, decl):
  303.         pass
  304.  
  305.     
  306.     def handle_pi(self, data):
  307.         pass
  308.  
  309.     
  310.     def unknown_decl(self, data):
  311.         self.error('unknown declaration: %r' % (data,))
  312.  
  313.     
  314.     def unescape(self, s):
  315.         if '&' not in s:
  316.             return s
  317.         
  318.         s = s.replace('<', '<')
  319.         s = s.replace('>', '>')
  320.         s = s.replace(''', "'")
  321.         s = s.replace('"', '"')
  322.         s = s.replace('&', '&')
  323.         return s
  324.  
  325.  
  326.